package com.thm.tfast.core.aspect;

import cn.hutool.core.date.StopWatch;
import com.thm.tfast.core.annotation.Log;
import com.thm.tfast.core.enums.LogTypeEnum;
import com.thm.tfast.modules.sys.model.SysLog;
import com.thm.tfast.modules.sys.service.SysLogService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @ClassName SysLogAspect
 * @Author THM
 * @Date 2022/10/31 17:53
 * @Version 1.0
 * @Description 日志处理
 */
@Slf4j
@Aspect
@Component
public class SysLogAspect {

    @Resource
    private SysLogService sysLogService;

    @SneakyThrows
    @Around("@annotation(log)")
    public Object around(ProceedingJoinPoint point, Log log){
        String className = point.getTarget().getClass().getName();
        String methodName = point.getSignature().getName();
        SysLogAspect.log.debug("[类名]:{},[方法]:{}", className, methodName);
        SysLog sysLog = sysLogService.createSysLog(List.of(point.getArgs()), null);
        sysLog.setTitle(log.title());
        // 计算运行时间
        StopWatch stopWatch = StopWatch.create(className);
        stopWatch.start();
        Object obj;
        try {
            obj = point.proceed();
        } catch (Exception e) {
            sysLog.setType(LogTypeEnum.ERROR.getCode());
            sysLog.setException(e.getMessage());
            throw e;
        } finally {
            stopWatch.stop();
            sysLog.setTime(stopWatch.getTotalTimeMillis());
            //异步记录日志
            insertLog(sysLog);
        }
        return obj;
    }

    private void insertLog(SysLog sysLog){
        CompletableFuture.runAsync(()-> sysLogService.save(sysLog));
    }

}
